<template>
  <page-card title="连接器管理">
    <a-row type="flex"
           :gutter="16">
      <a-col :span="7">
        <div class="left-wrap">
          <div class="wrap-title">连接器</div>
          <div class="wrap-content">
            <div class="search-wrap">
              <a-input-search v-model="searchValue"
                              placeholder="请输入"
                              style="flex:1;margin-right: 10px;"
                              @search="onSearch" />
              <a-button type="primary"
                        @click="onAddRoot()">
                添加根级
              </a-button>
            </div>
            <a-tree v-if="connectorTreeList.length > 0"
                    :replace-fields="replaceFields"
                    :load-data="onLoadData"
                    :expandedKeys="expandedKeys"
                    :loadedKeys="loadedKeys"
                    @expand="onExpand"
                    @load="onLoad"
                    :tree-data="connectorTreeList">
              <template slot="action"
                        slot-scope="item">
                <div class="node-title-wrap">
                  <template v-if="API_TYPE_COLOR_MAP[item.nodeType]">
                    <div style="display:inline-block"
                         @click="onSelectTreeNode(item, MQ_TYPE_MAP[item.type] ? 'MQ' : 'API')">
                      <span class="connector-type"
                            :style="{'color': API_TYPE_COLOR_MAP[item.nodeType]}">{{ item.nodeType }}</span>
                      <span>{{ item.name }}</span>
                    </div>
                  </template>
                  <template v-else>
                    <span @click="onSelectTreeNode(item)">{{ item.name }}</span>
                  </template>
                  <span class="action-btn">
                    <a-popconfirm placement="topRight"
                                  destroyTooltipOnHide
                                  :title="`是否要删除【${item.name}】?`"
                                  @confirm="() => onDelete(item)">
                      <a-icon type="minus-circle"
                              style="color: #ff4d4f;"
                              v-if="isShowRemoveIcon(item)" />
                    </a-popconfirm>
                    <a-tooltip title="修改分类">
                      <a-icon type="edit"
                              v-if="isShowAddGroup(item)"
                              @click="onAddRoot(item, 'edit')"
                              style="margin-left: 5px;" />
                    </a-tooltip>
                    <a-tooltip title="添加分类">
                      <a-icon type="plus-square"
                              v-if="isShowAddGroup(item)"
                              @click="onAddRoot(item, 'add')"
                              style="margin-left: 5px;" />
                    </a-tooltip>
                    <template v-if="isShowAddIcon(item)">
                      <a-tooltip title="添加连接器"
                                 v-if="item.nodeType === 'GROUP'">
                        <a-icon type="plus-circle"
                                @click="onSelectTreeNode(item, 'CONNECTOR', true)"
                                style="margin-left: 5px;" />
                      </a-tooltip>
                      <a-tooltip title="添加接口"
                                 v-else>
                        <a-icon type="plus-circle"
                                @click="onSelectTreeNode(item, item.type === '1' ? 'API' : 'MQ', true)"
                                style="margin-left: 5px;" />
                      </a-tooltip>
                    </template>

                  </span>
                </div>
              </template>
            </a-tree>
            <a-empty v-else />
          </div>
        </div>
      </a-col>
      <a-col :span="17">
        <div class="right-wrap">
          <div class="wrap-title">{{ rightTitle }}</div>
          <div class="wrap-content">
            <!-- <AuthConfig :parentNode="selectTreeNode" /> -->
            <template v-if="selectTreeNode">
              <!-- 分组列表 -->
              <GroupList v-show="selectTreeNode.showRightType === 'GROUP'"
                         :selectNode="selectTreeNode" />
              <!-- 连接器组件 -->
              <ConnectorEdit v-show="selectTreeNode.showRightType === 'CONNECTOR'"
                             :parentNode="selectTreeNode"
                             :authConfigData="authConfigData"
                             @authConfig="onAuthConfig"
                             @sucess="onSearch" />
              <!-- 认证配置组件 -->
              <AuthConfig v-show="selectTreeNode.showRightType === 'AUTH'"
                          :parentNode="selectTreeNode"
                          @confirm="onAuthConfirm" />
              <!-- API组件 -->
              <ApiEdit v-show="selectTreeNode.showRightType === 'API'"
                       :parentNode="selectTreeNode"
                       @load="onApiLoad"
                       @sucess="onSearch" />
              <!-- MQ组件 -->
              <MqEdit v-show="selectTreeNode.showRightType === 'MQ'"
                      :parentNode="selectTreeNode"
                      @sucess="onSearch" />
            </template>
          </div>
        </div>
      </a-col>
    </a-row>
    <!-- 添加根级分组 -->
    <a-modal v-model="rootModal.visible"
             title="连接器分类"
             :confirm-loading="rootModal.loading"
             @cancel="onCancel()"
             @ok="onConfirm('groupForm')">
      <a-form-model :rules="rules"
                    ref="groupForm"
                    layout="horizontal"
                    :model="groupForm"
                    :label-col="labelCol"
                    :wrapper-col="wrapperCol">
        <a-form-model-item label="分类名称"
                           prop="name">
          <a-input v-model="groupForm.name"
                   allowClear />
        </a-form-model-item>
      </a-form-model>
    </a-modal>
  </page-card>
</template>

<script>
import { makeTreeDataStructure } from './server'
import ConnectorEdit from './components/ConnectorEdit.vue'
import GroupList from './components/GroupList.vue'
import ApiEdit from './components/ApiEdit.vue'
import MqEdit from './components/MqEdit.vue'
import AuthConfig from './components/AuthConfig.vue'
import { VALIDATION_TYPE_MAP, API_TYPE_COLOR_MAP, MQ_TYPE_MAP } from './config'
import { saveOrUpdateConnector, fetchConnectorTree, fetchAPIListbyConnector, fetchDeleteGroup, fetchDeleteInstance } from '../../api/connector-manage'
export default {
  name: 'YfConnectorList',
  components: {
    ConnectorEdit,
    GroupList,
    AuthConfig,
    ApiEdit,
    MqEdit
  },
  data () {
    return {
      connectorTreeList: [],
      VALIDATION_TYPE_MAP: VALIDATION_TYPE_MAP,
      API_TYPE_COLOR_MAP: API_TYPE_COLOR_MAP,
      MQ_TYPE_MAP: MQ_TYPE_MAP,
      replaceFields: {
        children: 'children',
        title: 'name',
        key: 'id'
      },
      connectorData: null,
      authConfigData: {},
      expandedKeys: [],
      loadedKeys: [],
      selectTreeNode: null,
      removeNodeVisible: false,
      searchValue: '',
      rootModal: {
        loading: false,
        visible: false,
        node: null
      },
      rules: {
        name: [
          { required: true, message: '请输入分类名称', trigger: 'blur' },
          { min: 2, max: 10, message: '长度为2~10个字符', trigger: 'blur' }
        ]
      },
      labelCol: { span: 4 },
      wrapperCol: { span: 14 },
      groupForm: {
        id: '',
        name: ''
      }
    }
  },
  provide () {
    return {
      getApp: this.getApp
    }
  },
  created () {
    this.initConnectorTree()
  },
  computed: {
    rightTitle: function () {
      if (this.selectTreeNode) {
        if (this.selectTreeNode.isAdd) {
          return this.selectTreeNode.showRightType === 'CONNECTOR' ? `${this.selectTreeNode.label}【新增连接器】` : `${this.selectTreeNode.label}【新增接口】`
        } else {
          return this.selectTreeNode.label
        }
      } else {
        return ''
      }
    }
  },
  methods: {
    // 获取当前组件实例
    getApp () {
      return {
        connectorData: this.connectorData
      }
    },
    async initConnectorTree () {
      const res = await fetchConnectorTree({ name: this.searchValue })
      try {
        // 构造转换成前端所需数据结构
        makeTreeDataStructure(res)
        this.connectorTreeList = JSON.parse(JSON.stringify(res))
        this.expandedKeys = []
        this.loadedKeys = []
        // 默认查询第一个节点列表
        if (this.connectorTreeList.length > 0) {
          this.selectTreeNode = this.connectorTreeList[0]
          this.selectTreeNode.showRightType = 'GROUP'
        }
      } catch (error) {
        this.connectorTreeList = []
      }
    },
    // 树形节点搜索
    onSearch () {
      this.initConnectorTree()
    },
    // API认证配置事件触发
    onAuthConfig (data) {
      this.connectorData = data
      this.selectTreeNode.showRightType = data.showType
      this.selectTreeNode.isCache = true
      this.selectTreeNode = { ...this.selectTreeNode }
    },
    onApiLoad (data) {
      this.connectorData = data
    },
    onExpand (expandedKeys) {
      this.expandedKeys = [...expandedKeys]
    },
    onLoad (loadedKeys) {
      this.loadedKeys = [...loadedKeys]
    },
    onLoadData (treeNode) {
      return new Promise(resolve => {
        if ((Array.isArray(treeNode.dataRef.children) && treeNode.dataRef.children.length > 0) || treeNode.dataRef.type === 'group') {
          resolve()
          return
        }
        fetchAPIListbyConnector({
          connectorId: treeNode.eventKey
        }).then((res) => {
          treeNode.dataRef.children = (res || []).map((item) => {
            return {
              ...item,
              label: item.name,
              type: treeNode.dataRef.type,
              nodeType: (function () {
                if (treeNode.dataRef.type === '1') {
                  return item.requestMethod ? (item.requestMethod === '1' ? 'GET' : 'POST') : 'GET'
                } else {
                  return MQ_TYPE_MAP[treeNode.dataRef.type]
                }
              })(),
              isLeaf: true,
              scopedSlots: {
                title: 'action'
              }
            }
          })
          this.connectorTreeList = [...this.connectorTreeList]
          resolve()
        })
      })
    },
    onAddRoot (node = null, type) {
      this.rootModal.visible = true
      this.rootModal.node = node
      if (node && type === 'edit') {
        // 在form组件完全加载之后，再进行赋值操作，否则form resetFields方法会重置为加载之前的初始赋值
        this.$nextTick(() => {
          this.groupForm.id = node.id
          this.groupForm.name = node.name
        })
      } else {
        this.groupForm = {
          id: '',
          name: ''
        }
      }
    },
    onCancel (formName) {
      this.$refs[formName].resetFields()
    },
    onConfirm (formName) {
      this.$refs[formName].validate(valid => {
        if (valid) {
          this.rootModal.loading = true
          let pid = ''
          if (this.rootModal.node) {
            pid = this.groupForm.id ? this.rootModal.node.pid : this.rootModal.node.id
          }
          saveOrUpdateConnector({
            id: this.groupForm.id,
            name: this.groupForm.name,
            pid: pid,
            type: '0'
          }).then(() => {
            this.initConnectorTree()
            this.rootModal.visible = false
          }).finally(() => {
            this.rootModal.loading = false
          })
        } else {
          return false
        }
      })
    },
    // 是否显示删除按钮
    isShowRemoveIcon (node = null) {
      // 分组和连接器需要判断子级是否为空，不为空则不能删除
      if (node.nodeType === 'GROUP' || node.nodeType === 'CONNECTOR') {
        return !(Array.isArray(node.children) && node.children.length > 0)
      } else {
        return true
      }
    },
    // 是否显示添加分组按钮
    isShowAddGroup (node = null) {
      // 只有节点为分组可继续添加分组
      return node.nodeType === 'GROUP'
    },
    // 是否显示添加接口按钮
    isShowAddIcon (node = null) {
      // 树形接口列表项默认不显示添加按钮
      return !(node.nodeType !== 'GROUP' && node.nodeType !== 'CONNECTOR')
    },
    onSelectTreeNode (node, type = null, isAdd = false) {
      this.selectTreeNode = node
      this.selectTreeNode.showRightType = type || node.nodeType // showRightType: 用于判断右侧内容展示不同的组件
      this.selectTreeNode.isAdd = isAdd // isAdd: 判断是否是新增操作
      if (isAdd) {
        this.connectorData = null
      }
    },
    async onDelete (node) {
      if (node.nodeType === 'GROUP' || node.nodeType === 'CONNECTOR') {
        await fetchDeleteGroup(node.id)
      } else {
        await fetchDeleteInstance(node.id, node.type)
      }
      this.initConnectorTree()
    },
    // 认证配置确认事件
    onAuthConfirm (data) {
      this.selectTreeNode.showRightType = 'CONNECTOR'
      this.authConfigData = data
    }
  }
}
</script>

<style lang="less" scoped>
.search-wrap {
  margin: 10px 0;
  padding: 0 5px;
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.left-wrap,
.right-wrap {
  border: 1px solid #eee;
  border-radius: 5px;
  height: 100%;
}

.wrap-content {
  padding: 10px 15px;
  ::v-deep.ant-tree {
    position: relative;
  }
  .connector-type {
    font-size: calc(var(--font-size-14) - 1px);
    margin-right: 10px;
    font-weight: 500;
  }
  .node-title-wrap {
    .action-btn {
      position: absolute;
      right: 0;
    }
  }
}
.wrap-title {
  text-align: center;
  padding: 15px;
  border-bottom: 1px solid #eee;
  height: 52px;
}
.right-wrap {
  .wrap-title {
    text-align: left;
  }
  .wrap-content {
    padding: 30px 20px;
  }
}
</style>